package NB;

import java.io.BufferedReader;
import java.io.FileReader;

import track2.context.Config;
import track2.data.DescriptionToken;
import track2.data.PurchaseKeywordToken;
import track2.data.QueryToken;
import track2.data.TitleToken;
import track2.data.UserProfile;
import track2.result.Result;

public class nbTest {

	/**
	 * Test function for naive bayes
	 * 
	 * @return Result
	 */
	public static IdnbFeature idfeature;
	
	public static Result test(nbFeature feature, String testFilePath) {
		Result result = new Result();
		result.resultScore = new double[Config.testInstanceNum];
		int index = 0;
		//idfeature = IdnbFeature.getObject();
		try {
			System.out.println("Naive Bayes begin test...");
			BufferedReader br = new BufferedReader(new FileReader(testFilePath));
			String line;
			while ((line = br.readLine()) != null) {
				if (index % 1000000 == 0)
					System.out.println(index);
				String[] paras = line.split("\\t");
				int queryID = Integer.parseInt(paras[5]);
				int purchaseID = Integer.parseInt(paras[6]);
				int titleID = Integer.parseInt(paras[7]);
				int descriptionID = Integer.parseInt(paras[8]);
				int userID = Integer.parseInt(paras[9]);

				String query = getToken("Q", queryID);
				String title = getToken("T", titleID);
				String purchase = getToken("P", purchaseID);
				String description = getToken("D", descriptionID);
				String user = getToken("U", userID);

				double[] prob = new double[2];// 0 is for click probability, 1
												// for unclick probability
				// prior probability
				prob[0] += Math.log(feature.click);
				prob[1] += Math.log((1 - feature.click));

				if (query != null)
					getClickProb("Q", query, feature, prob);
				if (title != null)
					getClickProb("T", title, feature, prob);
				if (purchase != null)
					getClickProb("P", purchase, feature, prob);
//				if (description != null)
//					getClickProb("D", description, feature, prob);
				if (user != null)
					getClickProb("U", user, feature, prob);

				// 1/(1+e^(log(B)-log(A));
				result.resultScore[index] = 1.0 / (1.0 + Math.exp(prob[1]
						- prob[0]));
				index++;

			}
			br.close();
			System.out.println("Naive Bayes test finished...");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 
	 * @return click probability
	 */
	public static void getClickProb(String flag, String value,
			nbFeature feature, double[] prob) {
		String[] tokens = value.split("\\|");
		if (flag.equals("Q")) {// QueryID
			getClick(feature.queryClick, feature.queryNotClick, tokens, prob);
		} else if (flag.equals("T")) {// TitleID
			getClick(feature.titleClick, feature.titleNotClick, tokens, prob);
		} else if (flag.equals("P")) {// PurchaseID
			getClick(feature.purchaseClick, feature.purchaseNotClick, tokens,
					prob);
		} else if (flag.equals("D")) {// DescriptionID
			getClick(feature.descriptionClick, feature.descriptionNotClick,
					tokens, prob);
		} else if (flag.equals("U")) {// UserID
			String[] gender = new String[1];
			gender[0] = tokens[0];
			String[] age = new String[1];
			age[0] = tokens[1];
			getClick(feature.genderClick, feature.genderNotClick, gender, prob);
			getClick(feature.ageClick, feature.ageNotClick, age, prob);
		}
	}

	private static void getClick(double[] queryClick, double[] queryNotClick,
			String[] tokens, double[] prob) {
		for (int i = 0; i < tokens.length; i++) {
			int token = Integer.parseInt(tokens[i]);
			if (queryClick[token] != -1) // -1 is NOVALUE
				prob[0] += Math.log(queryClick[token]);
			if (queryNotClick[token] != -1)// -1 is NOVALUE
				prob[1] += Math.log(queryNotClick[token]);
		}

	}

	// get tokens
	public static String getToken(String flag, int id) {
		String result = null;
		if (flag.equals("Q")) {// QueryID
			result = QueryToken.getInstance().getMap().get(id);
		} else if (flag.equals("T")) {// TitleID
			result = TitleToken.getInstance().getMap().get(id);
		} else if (flag.equals("P")) {// PurchaseID
			result = PurchaseKeywordToken.getInstance().getMap().get(id);
		} else if (flag.equals("D")) {// DescriptionID
			result = DescriptionToken.getInstance().getMap().get(id);
		} else if (flag.equals("U")) {// UserID
			result = UserProfile.getInstance().getMap().get(id);
		}
		return result;
	}
}
